package com.dcy.auth.biz.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.dcy.auth.biz.convert.UserInfoConvert;
import com.dcy.auth.biz.enums.AuthApiErrorCode;
import com.dcy.auth.biz.vo.in.LoginInVO;
import com.dcy.common.exception.BusinessException;
import com.dcy.satoken.model.LoginAccount;
import com.dcy.satoken.util.AdminLoginUtil;
import com.dcy.system.api.api.AuthApi;
import com.dcy.system.api.api.DeptApi;
import com.dcy.system.api.api.UserApi;
import com.dcy.system.api.dto.out.RoleListOutDTO;
import com.dcy.system.api.dto.out.UserInfoListOutDTO;
import com.dcy.system.api.enums.UserInfoStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author dcy
 * @description 登录service
 * @createTime 2022/12/29 10:46
 */
@Slf4j
@Service
public class LoginService {

    private final UserInfoConvert userInfoConvert = UserInfoConvert.INSTANCE;
    private static final BCryptPasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder();

    @DubboReference
    private UserApi userApi;
    @DubboReference
    private DeptApi deptApi;
    @DubboReference
    private AuthApi authApi;

    /**
     * 登录
     *
     * @param loginInVO
     * @return
     */
    public String login(LoginInVO loginInVO) {
        log.info("开始登录：{}", loginInVO.getUsername());
        UserInfoListOutDTO userInfoListOutDTO = userApi.getUserInfoByUsername(loginInVO.getUsername());
        if (userInfoListOutDTO == null) {
            throw new BusinessException(AuthApiErrorCode.USER_PASSWORD_ERROR);
        }
        if (UserInfoStatusEnum.DISABLE.getCode().equals(userInfoListOutDTO.getUserStatus())) {
            throw new BusinessException(AuthApiErrorCode.USER_LOCKED_ERROR);
        }
        if (!PASSWORD_ENCODER.matches(loginInVO.getPassword(), userInfoListOutDTO.getPassword())) {
            throw new BusinessException(AuthApiErrorCode.USER_PASSWORD_ERROR);
        }
        LoginAccount loginAccount = userInfoConvert.toLoginAccount(userInfoListOutDTO);
        // 设置权限
        loginAccount.setResources(authApi.getAuthRoleAndResourceByUserId(userInfoListOutDTO.getId()));
        if (StrUtil.isNotBlank(userInfoListOutDTO.getDeptId())) {
            loginAccount.setDeptName(deptApi.getById(userInfoListOutDTO.getDeptId()).getName());
        }
        List<RoleListOutDTO> authRoleListByUserId = authApi.getAuthRoleListByUserId(userInfoListOutDTO.getId());
        if (CollUtil.isNotEmpty(authRoleListByUserId)) {
            loginAccount.setRoleName(CollUtil.join(authRoleListByUserId.stream().map(RoleListOutDTO::getRoleName).collect(Collectors.toList()), ","));
        }
        // 设置数据权限
        final Boolean allDataScopeFlag = authApi.getAllDataScopeFlag(userInfoListOutDTO.getId());
        loginAccount.setAllDataScopeFlag(allDataScopeFlag);
        if (!allDataScopeFlag) {
            loginAccount.setDataScopes(authApi.getDataScopeListByUserId(userInfoListOutDTO.getId()));
        }
        return AdminLoginUtil.login(loginAccount);
    }

    /**
     * 获取用户信息
     *
     * @return
     */
    public LoginAccount getUserInfo() {
        return AdminLoginUtil.getUserInfo();
    }

    /**
     * 退出登录
     */
    public Boolean logout() {
        AdminLoginUtil.logout();
        return Boolean.TRUE;
    }

}
